import binascii
import base64
import abstract_decoder
from collections import Counter
import re


class CryptoHexDecoder(abstract_decoder.AbstractDecoder):
    """CryptoHex解码器"""
    def __init__(self):
        super().__init__("crypto_hex")
        self.results = []

    def is_valid(self, data, key=None):
        """检查字符串是否有效"""
        pattern = r"^[0-9a-fA-F]+$"
        return bool(re.fullmatch(pattern, data))

    def decode(self, data, key=None):
        """解码字符串"""
        self.encoded = data
        self._check_characteristics()

        # 步骤1: 尝试直接十六进制解码
        if self._try_direct_hex():
            return self.results[-1].get("decoded")

        # 步骤2: 尝试嵌套解码
        nested_result = self._try_nested_decoding()
        if nested_result:
            return nested_result.get("decoded")

        # 步骤3: 尝试编码变形
        transform_result = self._try_transformations()
        if transform_result:
            return transform_result.get("decoded")

        # 步骤4: 尝试与其他编码组合
        combo_result = self._try_encoding_combinations()
        if combo_result:
            return combo_result.get("decoded")

        # 步骤5: 自动化分析
        auto_result = self._auto_analyze()
        if auto_result:
            return auto_result.get("decoded")

        return "未能成功解码该字符串"

    def _check_characteristics(self):
        """检查字符串特征"""
        characteristics = {
            "length": len(self.encoded),
            "is_even_length": len(self.encoded) % 2 == 0,
            "hex_chars_only": all(c in "0123456789abcdefABCDEF" for c in self.encoded),
            "char_distribution": dict(Counter(self.encoded)),
        }
        self.results.append(
            {"step": "特征分析", "result": characteristics, "decoded": None}
        )
        return characteristics

    def _try_direct_hex(self):
        """尝试直接十六进制解码"""
        try:
            decoded = binascii.unhexlify(self.encoded).decode("utf-8")
            self.results.append(
                {"step": "直接十六进制解码", "result": "成功", "decoded": decoded}
            )
            return decoded
        except:
            self.results.append(
                {"step": "直接十六进制解码", "result": "失败", "decoded": None}
            )
            return None

    def _try_nested_decoding(self):
        """尝试嵌套解码"""
        # 尝试hex套hex
        direct_result = self._try_direct_hex()
        if (
            direct_result
            and all(c in "0123456789abcdefABCDEF" for c in direct_result)
            and len(direct_result) % 2 == 0
        ):
            nested = CryptoHexDecoder().decode(direct_result)
            if nested:
                self.results.append(
                    {"step": "嵌套十六进制解码", "result": "成功", "decoded": nested}
                )
                return nested

        # 尝试hex转base64
        try:
            bytes_data = binascii.unhexlify(self.encoded)
            base64_decoded = base64.b64decode(bytes_data).decode("utf-8")
            self.results.append(
                {"step": "HEX转Base64解码", "result": "成功", "decoded": base64_decoded}
            )
            return base64_decoded
        except:
            pass

        return None

    def _try_transformations(self):
        """尝试编码变形"""
        transformations = [
            ("字符串反转", lambda s: s[::-1]),
            (
                "字节交换",
                lambda s: "".join([s[i : i + 2][::-1] for i in range(0, len(s), 2)]),
            ),
            ("常见XOR(0x55)", self._xor_decode),
            ("常见XOR(0xFF)", lambda s: self._xor_decode(s, 0xFF)),
        ]

        for name, transform_func in transformations:
            transformed = transform_func(self.encoded)
            try:
                decoded = binascii.unhexlify(transformed).decode("utf-8")
                self.results.append(
                    {
                        "step": f"编码变形 - {name}",
                        "result": "成功",
                        "decoded": decoded,
                        "transformed": transformed,
                    }
                )
                return decoded
            except:
                self.results.append(
                    {
                        "step": f"编码变形 - {name}",
                        "result": "失败",
                        "decoded": None,
                        "transformed": transformed,
                    }
                )
                continue

        return None

    def _xor_decode(self, s, key=0x55):
        """XOR解码"""
        try:
            bytes_data = binascii.unhexlify(s)
            return bytes([b ^ key for b in bytes_data]).hex()
        except:
            return s

    def _try_encoding_combinations(self):
        """尝试与其他编码组合"""
        # 尝试ASCII码解码
        if len(self.encoded) % 2 == 0:
            try:
                ascii_str = "".join(
                    [
                        chr(int(self.encoded[i : i + 2], 16))
                        for i in range(0, len(self.encoded), 2)
                    ]
                )
                if ascii_str.isprintable():
                    self.results.append(
                        {"step": "ASCII码解码", "result": "成功", "decoded": ascii_str}
                    )
                    return ascii_str
            except:
                pass

        # 尝试Unicode解码
        try:
            unicode_str = self.encoded.encode("utf-8").decode("unicode_escape")
            if unicode_str != self.encoded:
                self.results.append(
                    {"step": "Unicode解码", "result": "成功", "decoded": unicode_str}
                )
                return unicode_str
        except:
            pass

        return None

    def _auto_analyze(self):
        """自动化分析"""
        # 这里可以实现更复杂的自动分析逻辑
        # 例如尝试多种组合方式

        # 示例：尝试hex -> bytes -> utf8/ascii/base64等
        try:
            bytes_data = binascii.unhexlify(self.encoded)

            # 尝试utf-8
            try:
                decoded = bytes_data.decode("utf-8")
                self.results.append(
                    {
                        "step": "自动化分析 - HEX转UTF-8",
                        "result": "成功",
                        "decoded": decoded,
                    }
                )
                return decoded
            except:
                pass

            # 尝试base64
            try:
                decoded = base64.b64decode(bytes_data).decode("utf-8")
                self.results.append(
                    {
                        "step": "自动化分析 - HEX转Base64",
                        "result": "成功",
                        "decoded": decoded,
                    }
                )
                return decoded
            except:
                pass

        except:
            pass

        return None

    def get_analysis_report(self):
        """获取分析报告"""
        report = "=== CryptoHex 分析报告 ===\n"
        report += f"原始字符串: {self.encoded}\n\n"

        for step in self.results:
            report += f"步骤: {step['step']}\n"
            report += f"结果: {step['result']}\n"
            if "decoded" in step and step["decoded"]:
                report += f"解码结果: {step['decoded']}\n"
            if "transformed" in step:
                report += f"变形后: {step['transformed']}\n"
            report += "-" * 40 + "\n"

        return report


# 使用示例
if __name__ == "__main__":
    with open("test-data/hex.txt", "r") as f:
        encoded_str = f.read()
    crypto = CryptoHexDecoder()
    result = crypto.decode(encoded_str)
    print("最终解码结果:", result)
